﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Data.Linq;
using Quocity.Entities;
using System.Configuration;
using System.ServiceModel.Activation;

namespace QuocityService
{
    // NOTA: puede usar el comando "Rename" del menú "Refactorizar" para cambiar el nombre de clase "QuocityPrivateService" en el código, en svc y en el archivo de configuración a la vez.
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class QuocityPrivateService : IQuocityPrivateService
    {

        int IQuocityPrivateService.AddItinerary(int cityId, string name, string googleUserId)
        {
            try
            {
                using (DataContext context = new DataContext(ConfigurationManager.ConnectionStrings["QuocityConnectionString"].ConnectionString))
                {

                    Itinerary itinerary = new Itinerary()
                    {
                        CityId = cityId,
                        Name = name
                    };
                    itinerary.SetGoogleUserId(googleUserId);
                    context.GetTable<Itinerary>().InsertOnSubmit(itinerary);


                    context.SubmitChanges();
                    return itinerary.ItineraryId;

                }
            }
            catch (Exception)
            {
                //ToDo
                return -1;
            }
        }

        public bool UpdateItineraryName(int itineraryId, string newName, string googleUserId)
        {
            try
            {
                using (DataContext context = new DataContext(ConfigurationManager.ConnectionStrings["QuocityConnectionString"].ConnectionString))
                {
                    var itinerary = (from i in context.GetTable<Itinerary>()
                                     where i.ItineraryId == itineraryId && i.GetGoogleUserId() == googleUserId
                                     select i).FirstOrDefault();
                    if (itinerary != null)
                    {
                        itinerary.Name = newName;
                        context.SubmitChanges();
                        return true;
                    }
                    return false;
                    
                }
            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool UpdateItineraryDescription(int itineraryId, string newDescription, string googleUserId)
        {

            try
            {
                using (DataContext context = new DataContext(ConfigurationManager.ConnectionStrings["QuocityConnectionString"].ConnectionString))
                {
                    var itinerary = (from i in context.GetTable<Itinerary>()
                                     where i.ItineraryId == itineraryId && i.GetGoogleUserId() == googleUserId
                                     select i).FirstOrDefault();

                    if (itinerary != null)
                    {
                        itinerary.Description = newDescription;
                        context.SubmitChanges();
                        return true;

                    }
                    return false;
                    
                }
            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool UpdateItineraryVisibility(int itineraryId, bool isPublic, string googleUserId)
        {

            try
            {
                using (DataContext context = new DataContext(ConfigurationManager.ConnectionStrings["QuocityConnectionString"].ConnectionString))
                {
                    var itinerary = (from i in context.GetTable<Itinerary>()
                                     where i.ItineraryId == itineraryId && i.GetGoogleUserId() == googleUserId
                                     select i).FirstOrDefault();

                    if (itinerary != null)
                    {
                        itinerary.Public = isPublic;
                        context.SubmitChanges();
                        return true;
                    }
                    return false;
                    
                }
            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool MarkItinerary(int itineraryId, int mark, string googleUserId)
        {

            try
            {
                using (DataContext context = new DataContext(ConfigurationManager.ConnectionStrings["QuocityConnectionString"].ConnectionString))
                {
                    var itinerary = (from i in context.GetTable<Itinerary>()
                                     where i.ItineraryId == itineraryId
                                     select i).FirstOrDefault();

                    if (itinerary != null)
                    {
                        itinerary.Mark = (itinerary.Mark * itinerary.NumberOfMarks + mark) / ++itinerary.NumberOfMarks;
                        
                        context.SubmitChanges();
                        return true;
                    }
                    return false;
                   
                }

            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool DeleteItinerary(int itineraryId, string googleUserId)
        {

            try
            {
                using (DataContext context = new DataContext(ConfigurationManager.ConnectionStrings["QuocityConnectionString"].ConnectionString))
                {
                    var itinerary = (from i in context.GetTable<Itinerary>()
                                     where i.ItineraryId == itineraryId && i.GetGoogleUserId() == googleUserId
                                     select i).FirstOrDefault();

                    if (itinerary != null)
                    {
                        context.GetTable<Itinerary>().DeleteOnSubmit(itinerary);
                        context.SubmitChanges();
                        return true;
                    }
                    return false;
                }

            }
            catch (Exception)
            {
                return false;
            }
        }

        public int AddItineraryItem(int itineraryId, string name, float longitude, float latitude, string googleUserId)
        {

            try
            {
                using (DataContext context = new DataContext(ConfigurationManager.ConnectionStrings["QuocityConnectionString"].ConnectionString))
                {
                    var itinerary = (from i in context.GetTable<Itinerary>()
                                     where i.ItineraryId == itineraryId && i.GetGoogleUserId() == googleUserId
                                     select i).FirstOrDefault();

                    short? lastSortIndex = (from ii in context.GetTable<ItineraryItem>()
                                            orderby ii.SortIndex descending
                                            select ii.SortIndex).FirstOrDefault();

                    if (itinerary != null)
                    {
                        ItineraryItem itineraryItem = new ItineraryItem()
                        {
                            Name = name,
                            Longitude = longitude,
                            Latitude = latitude,
                            SortIndex = (short)(lastSortIndex.HasValue ? lastSortIndex.Value + 1 : 1)
                        };
                        itinerary.ItineraryItems.Add(itineraryItem);
                        context.SubmitChanges();
                        return itineraryItem.ItemId;
                    }
                    return -1;

                }
            }
            catch (Exception)
            {
                return -1;
            }
        }

        public bool UpdateItineraryItemSortIndex(int itineraryId, int itineraryItemId, short newSortIndex, string googleUserId)
        {

            try
            {
                using (DataContext context = new DataContext(ConfigurationManager.ConnectionStrings["QuocityConnectionString"].ConnectionString))
                {
                    DataLoadOptions loadOptions = new DataLoadOptions();
                    loadOptions.LoadWith<ItineraryItem>(ii => ii.Itinerary);


                    var itineraryItem = (from ii in context.GetTable<ItineraryItem>()
                                         where ii.ItineraryId == itineraryId && ii.ItemId == itineraryItemId && ii.Itinerary.GetGoogleUserId() == googleUserId
                                         orderby ii.SortIndex ascending
                                         select ii).FirstOrDefault();

                    if (itineraryItem != null)
                    {
                        if (itineraryItem.SortIndex < newSortIndex)
                        {
                            var itemsToChange = (from ii in context.GetTable<ItineraryItem>()
                                                 where ii.SortIndex > itineraryItem.SortIndex && ii.SortIndex <= newSortIndex
                                                 select ii);
                            foreach (var item in itemsToChange)
                            {
                                item.SortIndex -= 1;
                            }
                            itineraryItem.SortIndex = newSortIndex;
                        }
                        else if (itineraryItem.SortIndex > newSortIndex)
                        {
                            var itemsToChange = (from ii in context.GetTable<ItineraryItem>()
                                                 where ii.SortIndex < itineraryItem.SortIndex && ii.SortIndex >= newSortIndex
                                                 select ii);
                            foreach (var item in itemsToChange)
                            {
                                item.SortIndex += 1;
                            }
                            itineraryItem.SortIndex = newSortIndex;
                        }
                        else
                        {
                            return true;
                        }
                        context.SubmitChanges();
                        return true;

                    }
                    return false;
                }
            }
            catch (Exception)
            {
                return false;
            }

        }

        public bool UpdateItineraryNotes(int itineraryId, int itineraryItemId, string newNotes, string googleUserId)
        {

            try
            {
                using (DataContext context = new DataContext(ConfigurationManager.ConnectionStrings["QuocityConnectionString"].ConnectionString))
                {
                    DataLoadOptions loadOptions = new DataLoadOptions();
                    loadOptions.LoadWith<ItineraryItem>(ii => ii.Itinerary);


                    var itineraryItem = (from ii in context.GetTable<ItineraryItem>()
                                         where ii.ItineraryId == itineraryId && ii.ItemId == itineraryItemId && ii.Itinerary.GetGoogleUserId() == googleUserId
                                         orderby ii.SortIndex ascending
                                         select ii).FirstOrDefault();
                    if (itineraryItem != null)
                    {
                        itineraryItem.Notes = newNotes;
                        context.SubmitChanges();
                        return true;
                    }
                    return false;
                }
            }
            catch (Exception)
            {
                return false;
            }
        }
    }
}
